<?php

namespace app\task\cron\coupon;

use app\model\CouponOrder;
use think\Exception;
use think\facade\Log;
use yunwuxin\cron\Task;
use think\facade\Db;
use app\common\model\FinanceStat;

/**
 * 权益订单返佣结算
 *
 */
class SettleOrder extends Task
{
    /**
     * 结算频率：每天凌晨结算一次
     */
    protected function configure()
    {
        // 分 时 日 月 周
        $this->expression = '* * * * *';
//        $this->expression = '0 1 * * *';
    }

    /**
     * 转化类型
     * @var array
     */
    public $trsType = [
        PRODUCT_COUPON_SERV => BALANCE_COUPON_COMMISS,
        PRODUCT_TRAVEL_OIL_SERV => BALANCE_TRAVEL_OIL_COMMISS,
        PRODUCT_AROUND_SHOP_SERV => BALANCE_AROUND_COMMISS,
        PRODUCT_FOOD_SHOP_SERV => BALANCE_FOOD_COMMISS,
        PRODUCT_SECKILL_SERV => BALANCE_MEITUAN_SEACKILL_COMMISS,
        PRODUCT_METUAN_SERV => BALANCE_TACKOUT_MEITUAN_DAODIAN,//到店
        PRODUCT_ELE_SERV => BALANCE_TACKOUT_ELE,
        PRODUCT_MEITUAN_TAKEOUT_SERV => BALANCE_TACKOUT,
        PRODUCT_MOBILE_CPS_SERV => BALANCE_MOBILE_CPS_SERV,
    ];

    /**
     * 执行指令.
     */
    protected function handle()
    {
        echo '开始权益佣金结算' . PHP_EOL;
        $lockKey = 'coupon_order_profit_lock_key1';
        $lockVal = cache($lockKey);
        if ($lockVal) {
            echo '还在处理呢' . PHP_EOL;

            return true;
        }

        cache($lockKey, 1, 1200);


        $done = 0;
        CouponOrder::query()
            ->where('agent_settle_status', 2)
            ->where('settle_type', SETTLE_TYPE_PROFIT)
            ->where('settled_at', '<', date('Y-m-d H:i:s'))
            ->chunk(30, function ($list) use (&$done) {
//                $list = $list->toArray();
                if (empty($list)) {
                    return false;
                }
                foreach ($list as $order) {
                    /**
                     * @var CouponOrder $order
                     */

                    Log::info('开始结算订单佣金id:'.$order->id);

                    $balanceType =$this->trsType[$order->serv_type]??'';

                    if (empty($balanceType)){
                        Log::error('没有配置结算佣金记录类型:'.$order->serv_type);
                        continue;
                    }
                    if (
                        $order->status != CouponOrder::C_STATUS_RECHARGE_SUCCESS ||
                        $order->refund_status != CouponOrder::C_REFUND_STATUS_NO||
                        $order->settle_type != SETTLE_TYPE_PROFIT
                    ) {
                        $order->agent_settle_status = CouponOrder::C_AGENT_SETTLE_STATUS_NO;
                        $order->log.='结算方式不是佣金结算，或者status不是成功的状态，状态改为不结算';
                        $order->save();
                        continue;
                    }

                    // 防止重复结算
                    $exists = Db::name('agent_balance_log')
                        ->where('type', $balanceType)
                        ->where('quote_id', $order->id)
                        ->value('id');
                    if ($exists) {
                        $order->agent_settle_status = CouponOrder::C_AGENT_SETTLE_STATUS_SUCCESS;
                        $order->log.='重复插入改为结算成功';
                        $order->save();
                        continue;
                    }

                    Db::startTrans();
                    try {
                        $profitBalance = Db::name('agent')
                            ->where('id', $order->agent_id)
                            ->value('profit_balance',0);
                        Db::name('agent')
                            ->where('id', $order->agent_id)
                            ->inc('profit_balance', $order->profit)
                            ->inc('total_profit',  $order->profit)
                            ->update([
                                'balance_last_updated_at' => date('Y-m-d H:i:s'),
                            ]);
                        Db::name('agent_balance_log')
                            ->insert([
                                'agent_id' => $order->agent_id,
                                'type' => $balanceType,
                                'amount' => $order->profit,
                                'old_balance' => $profitBalance,
                                'new_balance' => $profitBalance + $order->profit,
                                'remark' => $order->serv_type_name.'佣金结算：销售价：' . fen2yuan($order->pay_amount) . '元，结算价：' . fen2yuan($order->settle_price) . '元，利润：' . fen2yuan($order->profit) . '元。订单号：' . $order->order_id,
                                'quote_id' => $order->id,
                                'trade_no' => $order->order_id,
                            ]);

                        // 插入财务明细
                        FinanceStat::addSuccessRecord([
                            'order_id' => $order->order_id,
                            'order_type' => $order->serv_type??$order->type,
                            'settle_type' => $order->settle_type,
                            'amount' => $order->amount,
                            'sale_price' => $order->pay_amount,
                            'settle_price' => $order->settle_price,
                            'supplier_price' => $order->supplier_price,
                            'profit' => $order->profit,
                            'platform_profit' => $order->platform_profit,
                            'supplier_id' => $order->supplier_id,
                            'agent_id' => $order->agent_id,
                            'salesman_id' => $order->salesman_id ?? 0,
                            'remark' => '佣金结算',
                        ]);

                        $flag = Db::name('coupon_order')
                            ->where('id', $order->id)
                            ->where('agent_settle_status', CouponOrder::C_AGENT_SETTLE_STATUS_WAIT)
                            ->update([
                                'complete_at' => date('Y-m-d H:i:s'),
                                'agent_settle_status' => CouponOrder::C_AGENT_SETTLE_STATUS_SUCCESS,
                            ]);

                        if (!$flag){
                            throw new Exception('结算错误');
                        }

                        if ($flag) {
                            ++$done;

                            Db::commit();
                        } else {

                            Db::rollback();
                        }
                    } catch (\Exception $e) {
                        Db::rollback();
                        echo '报错了吧：' . $e->getMessage() . PHP_EOL;
                        var_dump($order);
                    }
                }
            });

        cache($lockKey, null);

        echo '权益佣金结算结束：成功结算 ' . $done . ' 单' . PHP_EOL;
    }
}
